home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / filepath.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  4KB  |  162 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *     filepath -
  19.  *        pathname convenience package
  20.  *
  21.  */
  22. #include "filepath.h"
  23. #include <string.h>
  24. #include <stdio.h>
  25. #include <pwd.h>
  26. #include <stdlib.h>
  27.  
  28. char *mymalloc();
  29.  
  30. char*
  31. pathbasename(char* path)
  32. {
  33.     char*    c = path;
  34.     char*    lastbase = 0;
  35.     int        length = 0;
  36.     char*    retstr;
  37.  
  38.     if (!path)
  39.     return 0;
  40.     
  41.     if (*c != '/') {        /* first name might be base */
  42.     lastbase = c;
  43.     }
  44.  
  45.     while (*c) {
  46.     if (*c == '/') {
  47.         switch (*(c+1)) {    /* look-ahead one char */
  48.         case '/':        /* c is a useless repetitious slash */
  49.         c++;
  50.         break;
  51.         case '\0':        /* c is a useless slash at end of path */
  52.         c++;
  53.         break;
  54.         default:
  55.         c++;        /* c+1 is first char of possible basename */
  56.         lastbase = c;
  57.         c++; length = 1;
  58.         break;
  59.         }
  60.     } else {        /* char in possible basename */
  61.         c++; length++;
  62.     }
  63.     }
  64.  
  65.     if (lastbase == 0) {    /* no basename found */
  66.     retstr = mymalloc(1);
  67.     retstr[0] = '\0';
  68.     return retstr;
  69.     }
  70.  
  71.     retstr = mymalloc(length+1);
  72.     strncpy(retstr, lastbase, length);  /* copy only base sans trailing /'s */
  73.     retstr[length] = '\0';
  74.  
  75.     return retstr;
  76. }
  77.  
  78.  
  79. char*
  80. pathdirname(char* path)
  81. {
  82.     char*    c;
  83.     char*    lastslash = 0;
  84.     char*    retstr;
  85.  
  86.     for (c = path; *c; c++) {
  87.     if (*c == '/') {
  88.         char* tmplastslash = c;
  89.         for (c++; *c == '/'; c++) {;}
  90.                     /* ignore redundant slashes */
  91.         if (*c) {        /* not superfluous trailing slash */
  92.         lastslash = tmplastslash;
  93.         } else {        /* was superfluous trailing slash */
  94.         break;
  95.         }
  96.     }
  97.     }
  98.  
  99.     if (lastslash == 0) {
  100.     if (path[0] == '/') {     /* path is "/" or has repeated "/" */
  101.         retstr = strdup("/");
  102.         return retstr;
  103.     } else {        /* basename only implies current dir "." */
  104.         retstr = strdup(".");
  105.         return retstr;
  106.     }
  107.     }
  108.  
  109.  
  110.     retstr = mymalloc(lastslash-path+1);
  111.     strncpy(retstr, path, lastslash-path);
  112.                 /* copy only dir sans trailing /'s */
  113.     retstr[lastslash-path] = '\0';
  114.  
  115.     return retstr;
  116. }
  117.  
  118.  
  119. char*
  120. pathexpandtilde(char* path)
  121. {
  122.     char*    c;
  123.     char    user[255];
  124.     char*    homedir;
  125.     char*    retstr;
  126.  
  127.     if (path[0] != '~') {
  128.     retstr = strdup(path);
  129.     return retstr;
  130.     }
  131.     
  132.     if (path[1] == '/' || path[1] == '\0') {    /* ~/... or ~ */
  133.     homedir = getenv("HOME");
  134.     c = &(path[1]);
  135.     } else {                    /* ~<user>/... */
  136.     struct passwd*    pwent;
  137.     int i;
  138.  
  139.     c = &(path[1]);
  140.     for (i=0; *c != '/' && *c != '\0'; c++, i++) {
  141.         user[i] = *c;
  142.     }
  143.     user[i] = '\0';
  144.  
  145.     pwent = getpwnam(user);
  146.     if (pwent == 0) {            /* no such user */
  147.         retstr = strdup(path);
  148.         return retstr;
  149.     }
  150.  
  151.     homedir = pwent->pw_dir;
  152.     }
  153.  
  154.     if (homedir == 0) {
  155.     homedir = "";                /* consistency with csh & ksh */
  156.     }
  157.     retstr = mymalloc(strlen(homedir) + strlen(c) + 1);
  158.     strcpy(retstr, homedir);
  159.     strcat(retstr, c);
  160.     return retstr;
  161. }
  162.